
package com.epam.android.training.level1.rss.parser;

import com.epam.android.training.level1.rss.FeedBo;
import com.epam.android.training.level1.rss.ItemBo;
import com.epam.android.training.level1.util.DateUtils;
import com.epam.android.training.level1.util.StringUtils;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import java.net.MalformedURLException;
import java.net.URL;

/**
 * @author Anton Novikov
 */
public class Rss20FeedParser extends BaseSaxFeedParser {

  // private static final String ROOT = "rss";

  private static final String CHANNEL = "channel";

  private static final String TITLE = "title";

  private static final String LINK = "link";

  private static final String DESC = "description";

  private static final String CAT = "category";

  private static final String IMG = "image";

  private static final String IMG_URL = "url";

  private static final String ITEM = "item";

  private static final String PUB_DATE = "pubDate";

  private FeedBo feed;

  private ItemBo item;

  private boolean hasImage;

  /**
   * Creates an instance of Rss20FeedParser.
   * 
   * @throws MalformedURLException
   */
  public Rss20FeedParser(String feedUrl) throws MalformedURLException {
    super(feedUrl);
  }

  public Rss20FeedParser(URL feedUrl) {
    super(feedUrl);
  }

  @Override
  protected FeedBo obtainResult() {
    return this.feed;
  }

  @Override
  public void startElement(String uri, String localName, String qName, Attributes attributes)
      throws SAXException {
    // process only feed elemens with default namespace.
    if (StringUtils.isNotEmpty(uri)) {
      return;
    }

    if (CHANNEL.equalsIgnoreCase(localName)) {
      feed = new FeedBo();
    } else if (ITEM.equalsIgnoreCase(localName) && feed != null) {
      item = new ItemBo();
      feed.addItem(item);
    } else if (IMG.equalsIgnoreCase(localName) && feed != null) {
      hasImage = true;
    }
  }

  @Override
  public void endElement(String uri, String localName, String qName) throws SAXException {
    // process only feed elemens with default namespace.
    if (feed == null || StringUtils.isNotEmpty(uri)) {
      clearCache();
      return;
    }

    // get element text if it has any and clear the cache after processing.
    String elementText = getText();

    if (ITEM.equalsIgnoreCase(localName)) {
      this.item = null;
    } else if (IMG.equalsIgnoreCase(localName)) {
      hasImage = false;
    } else if (TITLE.equalsIgnoreCase(localName)) {
      if (item != null) {
        item.setTitle(elementText);
      } else if (!hasImage) {
        feed.setTitle(elementText);
      }
    } else if (LINK.equalsIgnoreCase(localName)) {
      if (item != null) {
        item.setLink(elementText);
      } else if (!hasImage) {
        feed.setLink(elementText);
      }
    } else if (DESC.equalsIgnoreCase(localName) && item != null) {
      item.setDescription(elementText);
    } else if (IMG_URL.equalsIgnoreCase(localName) && hasImage
        && StringUtils.isNotEmpty(elementText)) {
      feed.setIconUrl(elementText);
    } else if (CAT.equalsIgnoreCase(localName) && item == null) {
      feed.addCategory(elementText);
    } else if (PUB_DATE.equalsIgnoreCase(localName) && item != null) {
      item.setPubDate(DateUtils.parseDate(elementText));
    }

    clearCache();
  }
}
